﻿using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.Logging;
using Serilog;
using sl= Serilog;

namespace CNative.Logging.Serilog
{
    public class SerilogLogger : Microsoft.Extensions.Logging.ILogger
    {
        private string name;
        private sl.Core.Logger _logger;

        public SerilogLogger(string _name)
        {
            name = _name;
            _logger = new sl.LoggerConfiguration().ReadFrom.Configuration(AppConfigurtaion.Configuration)
                 //.WriteTo.RollingFile(new ElasticsearchJsonFormatter(renderMessageTemplate:false),"c:/logs/log-{Date}.log")
                 //.WriteTo.Logger(config =>
                 //{
                 //    //config.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Information).ReadFrom.Configuration(AppConfig.Configuration.GetSection("Information"))
                 //})
                .CreateLogger();
            //new sl.LoggerConfiguration().CreateLogger();
        }
        public IDisposable BeginScope<TState>(TState state)
        {
            return null;
        }
        /// <summary>
        /// 判断是否开启记录
        /// </summary>
        public bool IsEnabled(LogLevel logLevel)
        {
            var convertLogLevel = ConvertLogLevel(logLevel);
            return _logger.IsEnabled(convertLogLevel);
        }
        /// <summary>
        /// 实现接口ILogger
        /// </summary>
        /// <typeparam name="TState"></typeparam>
        /// <param name="logLevel"></param>
        /// <param name="eventId"></param>
        /// <param name="state"></param>
        /// <param name="exception"></param>
        /// <param name="formatter"></param>
        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            if (formatter == null)
            {
                throw new ArgumentNullException(nameof(formatter));
            }

            var message = formatter(state, exception);

            if (String.IsNullOrEmpty(message) && exception == null)
                return;

            // Add event id, if available
            //if (eventId.Id != 0)
            //    _logger.BindProperty("EventId", eventId.Id,true, out new sl.Events.LogEventProperty());

           // _logger.SetProperty("TimeStamp", DateTime.UtcNow);
            //if (state != null)
            //{
            //    //if (state is IDictionary<string, object> stateProps)
            //    //{
            //    //    var ei = new MyLogEventInfo(ConvertLogLevel(logLevel), message, stateProps);

            //    //    _logger.Log(ei);
            //    //    return;
            //    //}
            //    if (state is IEnumerable<KeyValuePair<string, object>> stateProps)
            //    {
            //        foreach (var prop in stateProps)
            //        {
            //            // Logging the message template is superfluous
            //            _logger.SetProperty(prop.Key, prop.Value);
            //        }
            //    }
            //    else
            //    {
            //        // Otherwise, attach the entire object, using its type as the name
            //        _logger.SetProperty("Tags", state.ToString());
            //    }
            //}

            switch (logLevel)
            {
                case LogLevel.Critical://致命错误
                    _logger.Fatal(exception,message);
                    break;
                case LogLevel.Debug:
                    _logger.Debug(message);
                    break;
                case LogLevel.Trace://追踪
                    _logger.Verbose(message);
                    break;
                case LogLevel.Error:
                    _logger.Error(exception,message);
                    break;
                case LogLevel.Information:
                    _logger.Information(message);
                    break;
                case LogLevel.Warning:
                    _logger.Warning(message);
                    break;
                default:
                    _logger.Information(message);
                    break;
            }
        }

        public sl.Events.LogEventLevel ConvertLogLevel(LogLevel logLevel)
        {
            switch (logLevel)
            {
                case LogLevel.Trace:
                    return sl.Events.LogEventLevel.Verbose;
                case LogLevel.Debug:
                    return sl.Events.LogEventLevel.Debug;
                case LogLevel.Information:
                    return sl.Events.LogEventLevel.Information;
                case LogLevel.Warning:
                    return sl.Events.LogEventLevel.Warning;
                case LogLevel.Error:
                    return sl.Events.LogEventLevel.Error;
                case LogLevel.Critical:
                    return sl.Events.LogEventLevel.Fatal;
                case LogLevel.None:
                    return sl.Events.LogEventLevel.Information;
                default:
                    return sl.Events.LogEventLevel.Information;
            }
        }
        /*
         * Serilog定义的日志级别有：
            Verbose
            Debug
            Information
            Warning
            Error
            Fatal
         */

    }
}
